﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        //variables
        BroadcastClient broadcastClient;
        String updateText;
        bool resetBox = false;
        String msg_string;
        byte[] msg_bytes;
        // delims used to parse /roll
        char[] delims = { ' ', 'd', '+' };
        Thread listenThread = null;
        //username defined elsewhere in project, static here for testing
        String username = "Zach";

        //delegate function declaration
        delegate void UpdateGUI(string msg);

        //function passed to the delegate to update the textbox
        private void ShowMsg(string msg)
        {
            this.textBox1.AppendText(msg);
        }

        //thread to get listen for messages
        private void Listening()
        {
            while (true)
            {
                //if theres a message
                if (broadcastClient.IsListening && broadcastClient.MessagesReceived.Count() > 0)
                {
                    //get message
                    var message = broadcastClient.MessagesReceived.Dequeue();
                    //create new array of bytes
                    msg_bytes = new byte[message.Bytes.Length];
                    //copy message into array
                    Buffer.BlockCopy(message.Bytes, 0, msg_bytes, 0, msg_bytes.Length);
                    //get string from message
                    msg_string = Encoding.ASCII.GetString(msg_bytes, 0, msg_bytes.Length);
                    //call delagate function to update UI
                    this.Invoke(new UpdateGUI(ShowMsg), new object[] { msg_string });
                    //needed to not eat cpu?may remove
                    Thread.Sleep(500);
                }
            }
        }

        //initializations
        public Form1()
        {
            InitializeComponent();
            //may set this stuff up in designer.cs if ScrollBars and HorizontalAlignment are referenced
            textBox1.ScrollBars = ScrollBars.Vertical;
            textBox2.ScrollBars = ScrollBars.Vertical;
            textBox1.ReadOnly = true;
            textBox1.TextAlign = HorizontalAlignment.Left;

            broadcastClient = new BroadcastClient();
            listenThread = new Thread(new ThreadStart(Listening));
            listenThread.Start();
        }

        //function to parse when the user hits enter on the chat line/most code here
        private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
        {
            //if enter key was pressed
            if (e.KeyChar == (char)Keys.Enter)
            {
                //need to reset the box
                resetBox = true;
                //make sure empty strings arent sent and /roll messages are parsed here
                if (textBox2.Text != String.Empty && textBox2.Text.IndexOf("/roll") == -1)
                {
                    //the string to be sent, change "Zach" to Username defined elsewhere
                    updateText = (username+": " + textBox2.Text + "\r\n");
                    //encode the string into a byte buffer
                    byte[] send_buffer = Encoding.ASCII.GetBytes(updateText);
                    //send the string to all clients
                    broadcastClient.Send(send_buffer);
                    //if self IPaddress is not in sendlist, update your own text box with what you just sent
                    //remove this if your own Ip address is in your udpsendinglist so it doesnt appear twice
                    textBox1.AppendText(updateText);
                }
                //if the user is /roll compute the roll and send to others
                else if (textBox2.Text.IndexOf("/roll") != -1)
                {
                    //split the string
                    string[] words = textBox2.Text.Split(delims);
                    StringBuilder sb = new StringBuilder();
                    StringBuilder sb2 = new StringBuilder();
                    //random generator for rolls
                    Random rand=new Random();
                    int x = -1;
                    int y = -1;
                    int z = -1;
                    int rollValue = -1;
                    int totalRoll = 0;
                   //assuming /roll xdy+z, x and y will be at words[1] and words[2] respectively if input was correct
                    if (words.Length>=3)
                    {
                        //create string to send to others
                        sb.Append(username).Append(": Rolling ").Append(words[1]).Append("d").Append(words[2]);
                        //convert the string input to ints
                        try
                        {
                            x = Convert.ToInt32(words[1]);
                            y = Convert.ToInt32(words[2]);
                        }
                        catch (Exception t) { }
                        if (x == -1 || y == -1)
                        {
                            //did not give integer arguments, return
                            return;
                        }
                        //any .Append() statements are for stringbuilding for formatted output
                        sb2.Append(username).Append(": ").Append("( ");
                        //loop through y times to generate a random number and add to string to display what it was
                        for (int i = 0; i < x; i++)
                        {
                            rollValue = rand.Next(y);
                            sb2.Append(rollValue);
                            totalRoll += rollValue;
                            if (i < x - 1)
                            {
                                sb2.Append(" + ");
                            }
                        }
                        sb2.Append(" )");
                        //if the input was /roll xdy+z
                        if (words.Length ==4 )
                        {
                            try
                            {
                                z = Convert.ToInt32(words[3]);
                            }
                            catch (Exception t) { }
                            if (z == -1)
                            {
                                //bad integer argument
                                return;
                            }
                            sb.Append("+").Append(words[3]).Append("\r\n");
                            sb2.Append(" + ").Append(words[3]);
                            totalRoll += z;
                            sb2.Append(" = ").Append(totalRoll).Append("\r\n");

                        }
                        else //input was only /roll xdy
                        {
                            sb.Append("\r\n");
                            sb2.Append(" = ").Append(totalRoll).Append("\r\n");
                        }
                        //convert the stringbuilders to strings before sending them 
                        string s1 = sb.ToString();
                        string s2 = sb2.ToString();
                        //if self IPaddress is not in sendlist, update your own text box with what you just sent
                        //remove this if your own Ip address is in your udpsendinglist so it doesnt appear twice
                        textBox1.AppendText(s1);
                        textBox1.AppendText(s2);
                        //create buffer of bytes to send
                        byte[] send_buffer = Encoding.ASCII.GetBytes(s1);
                        //send the strings to all clients
                        broadcastClient.Send(send_buffer);
                        send_buffer = Encoding.ASCII.GetBytes(s2);
                        broadcastClient.Send(send_buffer);
                    }
                }

            }
        }

        //function to reset after the user hits enter on the chat line
        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (resetBox == true)
            {
                textBox2.ResetText();
                resetBox = false;
            }
        }
    }
}
